home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / ScreenSavers / BackSpaceViews / StarShipView.BackModule / Celestial.bproj / TiffManager.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  19.8 KB  |  733 lines

  1. #import "TiffManager.h"
  2. #import "Thinker.h"
  3.  
  4.                                 //I tested on 32Mb memory workstation
  5.                                 //it caused flicker if bigger than this
  6. #define MAXIMAGESIZE 150        //scale down if bigger than this
  7.                         
  8. #define SIZEINC  2                //increase image by number of pixels
  9.                                 // for each frame in animation
  10.                                 // this will affect how many images will
  11.                                 //be built for each animation
  12.                                 //the smaller the increment the smoother it is
  13.                                 
  14. //#define DEBUG
  15.  
  16. @implementation TiffManager
  17.  
  18. - init
  19. {
  20. char buf[MAXPATHLEN + 1];
  21.  
  22.     buf[0] = (int)NULL;
  23.     [super init];
  24.         
  25.     [self setHomeDirFile:buf];    //if there is a .Celestial folder in
  26.                                     //home directory - use it instead
  27.                                     
  28.     [self setTiffDirectory :buf];
  29.  
  30.     [self buildTiffStorage];
  31.         
  32.     if (totalTiffCount < 1){ //no files in .Celestial folder
  33.                                  // get them from module folder
  34.                                  
  35.         moduleDir = [[NXApp delegate] moduleDirectory:"StarShip"];
  36.         strcpy(buf, moduleDir);
  37.         strcat(buf,"/Celestial.bundle");
  38.         [self setTiffDirectory :buf];
  39.         [self buildTiffStorage];
  40.  
  41.     }
  42.     else
  43.         printf("Using files in .Celestial folder\n");                         
  44.  
  45.     tiffStorageIndex = 0;
  46.     animationIndex = 0;
  47.     numberProcessed = 0;
  48.     animFileIndex = 1;
  49.     maxAnimFiles = 0;
  50.     return self;
  51.     
  52. }
  53.  
  54.  
  55. //looks in the tiffStorage and starts creating images one at a time
  56. //and returns so that something else can be going on while this is
  57. //happening - returns Done when they are created.
  58.  
  59. - (BOOL)createTiffs
  60. {
  61.  
  62. char buf[MAXPATHLEN + 1];
  63. char *imageName = 0;
  64. char *animDirName = 0;
  65. ImageStruct imageStruct;
  66. int isSpin = 0;
  67. int isAnim = 0;
  68. int isMult = 0;
  69. #ifdef DEBUG
  70. NXRect DebugRect; 
  71. #endif
  72.  
  73.  
  74. NXPoint bogusPoint = {0.0,0.0};            //composite image to create cache
  75. NXRect    bogusRect = {0.0,0.0,1.0,1.0};  //composite image to create cache
  76. float increasePercent;
  77. NXPoint offset;
  78. NXPoint oldCenter;
  79. NXPoint newCenter;
  80. NXPoint newTrans;
  81. float distance,origAngle,maxDiagonal;
  82.         
  83.  
  84. // tiffStorageIndex = 0 to totalTiffCount-1
  85.  
  86.     isSpin = ((ImageStruct *)[tiffStorage elementAt:
  87.         tiffStorageIndex])->isSpin;
  88.     isMult = ((ImageStruct *)[tiffStorage elementAt:
  89.         tiffStorageIndex])->isMult;
  90.     isAnim = ((ImageStruct *)[tiffStorage elementAt:
  91.         tiffStorageIndex])->isAnim;
  92.     maxAnimFiles = ((ImageStruct *)[tiffStorage elementAt:
  93.         tiffStorageIndex])->maxAnimFiles;
  94.     imageName = ((ImageStruct *)[tiffStorage elementAt:
  95.         tiffStorageIndex])->imageName;
  96.     animDirName = ((ImageStruct *)[tiffStorage elementAt:
  97.         tiffStorageIndex])->animDirName;
  98.  
  99.  
  100.     switch(animationIndex){
  101.         case 0:  //create list - read in source Image
  102.             spinAdjustRect.origin.x = 0.0;
  103.             spinAdjustRect.origin.y = 0.0;
  104.             scaledImageRect.origin.x = 0.0;
  105.             scaledImageRect.origin.y = 0.0;
  106.         
  107.             localImageList = [[List alloc] init];
  108.             if(isAnim){ // drop down another level 
  109.                 sprintf(buf,"%s/%s.anim/%s.%d.tiff",tiffDirectory, animDirName,
  110.                 imageName,animFileIndex);
  111.                 animFileIndex++;
  112.                 if(animFileIndex > maxAnimFiles)
  113.                     animFileIndex = 1;
  114.             }
  115.             else
  116.                 sprintf(buf,"%s/%s.tiff",tiffDirectory,imageName);
  117.  
  118.             sourceImage = [[NXBitmapImageRep alloc] initFromFile:buf];
  119.             if(sourceImage == nil){
  120.                 printf("couldn't init NXBitmapImageRep from file %s\n",buf);
  121.                 animationIndex = 0;     //get next image if there is one
  122.                 tiffStorageIndex++;
  123.                 if(tiffStorageIndex > totalTiffCount)
  124.                     tiffStorageIndex = 0;
  125.                 numberProcessed++;
  126.                 break;
  127.             }
  128.             else animationIndex++;
  129.             if(isSpin){
  130.                 angle = 0.0;
  131.                 angleInc = randBetween(5,10); // objects will spin
  132.                                               //at different speeds each time
  133.             }
  134.             break;
  135.         case 1: //create temp buffer size of original image unless spinning
  136.                 // if spinning make buffer square
  137.  
  138.             [sourceImage getSize: &sourceImageSize];
  139.  
  140.  
  141.              if(sourceImageSize.width > sourceImageSize.height){
  142.                  widthIsSmaller = NO;
  143.                 scaledImageRect.size.height = 1; 
  144.                 //get percentage that 1 pixel is
  145.                 increasePercent = scaledImageRect.size.height /
  146.                  sourceImageSize.height;
  147.                 scaledImageRect.size.width = ceil(increasePercent *
  148.                  sourceImageSize.width);
  149.                 maxImageSize = (sourceImageSize.width > MAXIMAGESIZE) ?
  150.                  MAXIMAGESIZE: sourceImageSize.width; // smallest number    
  151.             }
  152.             else{
  153.                 widthIsSmaller = YES;
  154.                 scaledImageRect.size.width = 1; 
  155.                 //get percentage that 1 pixel is
  156.                 increasePercent = scaledImageRect.size.width /
  157.                  sourceImageSize.width;
  158.                 scaledImageRect.size.height = ceil(increasePercent *
  159.                  sourceImageSize.height);
  160.                 maxImageSize = (sourceImageSize.height > MAXIMAGESIZE) ?
  161.                  MAXIMAGESIZE: sourceImageSize.height; //smallest number
  162.                 
  163.             }
  164.             if(isSpin){ //use diagonal across original image to make a square
  165.                         // big enough to handle the image rotating
  166.                 maxDiagonal = sqrt((sourceImageSize.width *
  167.                  sourceImageSize.width) +
  168.                  (sourceImageSize.height * sourceImageSize.height));
  169.                 spinAdjustRect.size.height = spinAdjustRect.size.width
  170.                  = maxDiagonal;
  171.                  //get center of the new buffer
  172.                 spinCenter.x = spinAdjustRect.size.width / 2;     
  173.                 spinCenter.y = spinAdjustRect.size.height / 2;
  174.                      
  175.                 buffer = [[NXImage allocFromZone:[self zone]]
  176.                   initSize:&spinAdjustRect.size];
  177.             }
  178.             else{
  179.                 buffer = [[NXImage allocFromZone:[self zone]]
  180.                   initSize:&sourceImageSize];
  181.             } 
  182.      
  183.         animationIndex++;
  184.             break;
  185.         case 2: // scale and/or rotate - composite the image in buffer
  186.                 // this will keep alpha info
  187.                 // when you do the rotate, it rotates around origin
  188.                 // have to do a translate to bring center of image
  189.                 //back to the same place. drawIn method will do the
  190.                 //scaling automatically
  191.             if([buffer lockFocus]){
  192.                 if(isSpin){
  193.                 
  194.                     //caculate the real size of the animation images
  195.                 
  196.                     scaledDiagonal = sqrt((scaledImageRect.size.width *
  197.                       scaledImageRect.size.width)
  198.                      + (scaledImageRect.size.height *
  199.                      scaledImageRect.size.height));
  200.                     spinScaledImageRect.size.width = scaledDiagonal;
  201.                     spinScaledImageRect.size.height = scaledDiagonal;
  202.                 
  203.                     //find the orgin of where the scaled image is in buffer
  204.                 
  205.                     spinScaledImageRect.origin.x =(spinCenter.x -
  206.                       (scaledDiagonal/2));
  207.                     spinScaledImageRect.origin.y = (spinCenter.y -
  208.                       (scaledDiagonal/2));
  209.                     PSsetgray(0);// black out buffer
  210.                     NXRectFill(&spinScaledImageRect);//black out part of buffer
  211.             
  212.                     oldCenter.x = scaledImageRect.size.width / 2;
  213.                     oldCenter.y = scaledImageRect.size.height / 2;
  214.                     
  215.                     origAngle = atan(oldCenter.y/oldCenter.x); 
  216.                     
  217.                     
  218.                     distance = sqrt((oldCenter.x * oldCenter.x) +
  219.                       (oldCenter.y * oldCenter.y));
  220.                     angle += angleInc;        //increment the angle
  221.                      
  222.                     // convert degrees to radians
  223.  
  224.                     newCenter.x = cos(origAngle + (angle/57.30)) * distance;
  225.                     newCenter.y = sin(origAngle + (angle/57.30)) * distance;
  226.                     newTrans.x = (oldCenter.x - newCenter.x);
  227.                     newTrans.y = (oldCenter.y - newCenter.y);
  228.                     
  229.                     //now adjust to center of square buffer
  230.                     newTrans.x += (spinCenter.x - oldCenter.x);
  231.                     newTrans.y += (spinCenter.y - oldCenter.y);
  232.                     
  233.                     PStranslate(0.0 + newTrans.x,0.0 + newTrans.y);
  234.                     PSrotate(angle);
  235.  
  236.  
  237.                     if(![sourceImage drawIn:&scaledImageRect])
  238.                         printf("resizing image didn't work\n");
  239.                     [buffer unlockFocus];
  240.                 }
  241.                 else {
  242.                     if(![sourceImage drawIn:&scaledImageRect])
  243.                         printf("resizing image didn't work\n");
  244.                     [buffer unlockFocus];
  245.                 }
  246.             }
  247.             if(isAnim){
  248.                 [sourceImage free];
  249.             }
  250.             animationIndex++;
  251.             break;
  252.         case 3: // create new image correct size
  253.                 //build the image object with the actual image centered
  254.                 //in a black rectangle 8 pixels bigger on all sides
  255.                 // the stars have a max of width and height of 7 
  256.                 // and this guarantees that they will get blacked out
  257.                 // as the image is moving
  258.             if(isSpin){
  259.                 //calculate a square from the scaled image size
  260.                 // using the diagonal across the scaled image
  261.     
  262.                 adjustedRect.origin.x = 0.0;
  263.                 adjustedRect.origin.y = 0.0;
  264.                 adjustedRect.size.width = scaledDiagonal+16;
  265.                 adjustedRect.size.height = scaledDiagonal+16;
  266.                 
  267.                 //create the actual image 16 pixels bigger
  268.                     
  269.                 image = [[NXImage allocFromZone:[self zone]]
  270.                   initSize:&adjustedRect.size];
  271.                 
  272.                 //black it out 
  273.                 if([image lockFocus]){
  274.                     PSsetgray(0);
  275.                     NXRectFill(&adjustedRect);  //black out new image
  276.                     [image unlockFocus];
  277.                 }
  278.     
  279.             }
  280.             else{
  281.                 adjustedRect.origin.x = 0.0;
  282.                 adjustedRect.origin.y = 0.0;
  283.                 adjustedRect.size.width = scaledImageRect.size.width+16;
  284.                 adjustedRect.size.height = scaledImageRect.size.height+16;
  285.  
  286.                 
  287.                 //create the image
  288.     
  289.                 image = [[NXImage allocFromZone:[self zone]]
  290.                   initSize:&adjustedRect.size];
  291.                 if([image lockFocus]){
  292.                     PSsetgray(0);
  293.                     NXRectFill(&adjustedRect);  //black out new image
  294.                     [image unlockFocus];
  295.                 }
  296.             } 
  297.             animationIndex++;
  298.             break;
  299.         case 4: //composite into the image just created to get rid of alpha
  300.                 //center in middle of slightly bigger black image if rotating
  301.                 
  302.             offset.x = 8.0;
  303.             offset.y = 8.0;
  304.             if([image lockFocus]){
  305.                 if(isSpin){
  306.                     [buffer composite:NX_SOVER fromRect:&spinScaledImageRect
  307.                       toPoint:&offset];
  308.                 }
  309.                 else{
  310.                     [buffer composite:NX_SOVER fromRect:&scaledImageRect
  311.                       toPoint:&offset];
  312.                  }
  313.                  
  314.                 [image unlockFocus];
  315.             }
  316.             animationIndex++;
  317.             break;
  318.         case 5:    //now do phony composite, to build
  319.                 //offscreen cache - othewise a delay will happen
  320.                 //when you composite the first one
  321.              
  322. #ifdef DEBUG
  323.     //special debug code to see actual images being generated
  324.     // set PSsetgray(1) on previous calls to see the buffers
  325.     PSsetgray(0);
  326.     bogusPoint.x = 250.0;
  327.     bogusPoint.y = 250.0;
  328.     DebugRect.origin.x = 0.0;
  329.     DebugRect.origin.y = 0.0;
  330.     
  331.     [image getSize: &DebugRect.size];
  332.     [image composite:NX_SOVER fromRect:&DebugRect
  333.         toPoint:&bogusPoint];
  334.  
  335.     bogusPoint.x = 50.0;
  336.     bogusPoint.y = 50.0;
  337.              
  338.     [buffer getSize: &DebugRect.size];
  339.     [buffer composite:NX_SOVER fromRect:&DebugRect
  340.         toPoint:&bogusPoint];
  341.         
  342.     if(isSpin){            
  343.     PSmoveto(spinScaledImageRect.origin.x+50,
  344.      spinScaledImageRect.origin.y+50);
  345.     PSlineto(spinScaledImageRect.origin.x+50,
  346.     spinScaledImageRect.origin.y + spinScaledImageRect.size.height+50);
  347.     PSlineto(spinScaledImageRect.origin.x+50 + spinScaledImageRect.size.width,
  348.     spinScaledImageRect.origin.y + spinScaledImageRect.size.height+50);
  349.     PSlineto(spinScaledImageRect.origin.x + spinScaledImageRect.size.width+50,
  350.     spinScaledImageRect.origin.y+50);
  351.     PSlineto(spinScaledImageRect.origin.x+50,spinScaledImageRect.origin.y+50);
  352.     }
  353.     else {
  354.     PSmoveto(scaledImageRect.origin.x+50, scaledImageRect.origin.y+50);
  355.     PSlineto(scaledImageRect.origin.x+50, scaledImageRect.origin.y + 
  356.     scaledImageRect.size.height+50);
  357.     PSlineto(scaledImageRect.origin.x+50 + scaledImageRect.size.width,
  358.     scaledImageRect.origin.y + scaledImageRect.size.height+50);
  359.     PSlineto(scaledImageRect.origin.x + scaledImageRect.size.width+50,
  360.     scaledImageRect.origin.y+50);
  361.     PSlineto(scaledImageRect.origin.x+50, scaledImageRect.origin.y+50);
  362.     }
  363.     PSstroke();
  364. #else
  365.             [image composite:NX_DOVER fromRect:&bogusRect
  366.              toPoint:&bogusPoint];
  367. #endif
  368.  
  369.  
  370.             [localImageList addObject:image];    //add to list
  371.             
  372.             //calculate new size
  373.             if(widthIsSmaller){
  374.                 scaledImageRect.size.width += SIZEINC;
  375.                 scaledImageRect.size.width =
  376.                  ceil(scaledImageRect.size.width);
  377.                 scaledImageRect.size.height =
  378.                  ceil((scaledImageRect.size.width /
  379.                  sourceImageSize.width) * sourceImageSize.height);
  380.             }
  381.             else{
  382.                 scaledImageRect.size.height += SIZEINC;
  383.                 scaledImageRect.size.height = 
  384.                  ceil(scaledImageRect.size.height);
  385.                 scaledImageRect.size.width =
  386.                  ceil((scaledImageRect.size.height /
  387.                  sourceImageSize.height) * sourceImageSize.width);
  388.                      
  389.             }
  390.             
  391.             // if image is now bigger that max allowed size - exit on next pass
  392.             
  393.             if (scaledImageRect.size.width <= maxImageSize &&
  394.              scaledImageRect.size.height <= maxImageSize){
  395.                 animationIndex = 2;
  396.                  if(isAnim){ // set source image to next one 
  397.                     sprintf(buf,"%s/%s.anim/%s.%d.tiff",
  398.                      tiffDirectory, animDirName,imageName,animFileIndex);
  399.                     animFileIndex++;
  400.                     if(animFileIndex > maxAnimFiles)
  401.                         animFileIndex = 1;
  402.                         
  403.                     //create image for next pass if anim type
  404.                     sourceImage = [[NXBitmapImageRep alloc] initFromFile:buf];
  405.                     if(sourceImage == nil){//bad anim dir - go on to next image
  406.                         printf("couldn't init image file %s\n",buf);
  407.                         printf("skipping anim directory\n");
  408.                         if([buffer free] != nil)
  409.                             printf("buffer not freed\n");;
  410.                         numberProcessed++;
  411.                         tiffStorageIndex++;
  412.                         if(tiffStorageIndex > totalTiffCount)
  413.                             tiffStorageIndex = 0;
  414.                     }
  415.                 }
  416.             }
  417.             else{
  418.                 animationIndex++;
  419.             }
  420.             break;
  421.         case 6:    // finish image list
  422.             //printf("completing image # %d\n", tiffStorageIndex);
  423.             numberProcessed++;
  424.             if(!isAnim){
  425.                 [sourceImage free];
  426.             }
  427.             if([buffer free] != nil)
  428.                 printf("buffer not freed\n");
  429.  
  430.             imageStruct.imageList = localImageList;
  431.             imageStruct.imageName = imageName;
  432.             imageStruct.isSpin = isSpin;
  433.             imageStruct.isMult = isMult;
  434.             imageStruct.isAnim = isAnim;
  435.             imageStruct.animDirName = animDirName;
  436.             imageStruct.maxAnimFiles = maxAnimFiles;
  437.             [tiffStorage replaceElementAt:(unsigned int)tiffStorageIndex
  438.              with:&imageStruct];
  439.             animationIndex = 0;
  440.             animFileIndex = 1;
  441.             tiffStorageIndex++;
  442.             if(tiffStorageIndex >= totalTiffCount)
  443.                 tiffStorageIndex = 0;
  444.             break;
  445.     }
  446.  
  447.     if(numberProcessed >= MAXANIMATIONS || numberProcessed >= totalTiffCount){
  448.         numberProcessed = 0;
  449.         return NO;
  450.     }
  451.     else{
  452.         return YES;  //Tiffs still need to be built
  453.     }
  454. }
  455. - freeTiffs
  456. {
  457. //  all the tiffs brought in
  458. int ii;
  459.  
  460. List *imageList;
  461. int count;
  462. char *imageName = 0;
  463. char *animDirName = 0;
  464. ImageStruct imageStruct;
  465. int isSpin = 0;
  466. int isAnim = 0;
  467. int isMult = 0;
  468.  
  469.  
  470.     for(ii=0; ii < (int)[tiffStorage count];ii++){
  471.         imageList = (List *)((ImageStruct *)[tiffStorage
  472.         elementAt:ii])->imageList;
  473.         if(imageList != nil){
  474.             count = [imageList count];
  475.             if(count){
  476.                 [imageList freeObjects];
  477.                 [imageList free];
  478.                 //kind of ugly - all this to set the storage item
  479.                 //imageStruct.imageList to nil - otherwise
  480.                 // all other variables in storage record get wiped out
  481.                 
  482.                 isSpin = ((ImageStruct *)[tiffStorage elementAt:
  483.                   ii])->isSpin;
  484.                 isMult = ((ImageStruct *)[tiffStorage elementAt:
  485.                   ii])->isMult;
  486.                 isAnim = ((ImageStruct *)[tiffStorage elementAt:
  487.                   ii])->isAnim;
  488.                 maxAnimFiles = ((ImageStruct *)[tiffStorage elementAt:
  489.                   ii])->maxAnimFiles;
  490.                 imageName = ((ImageStruct *)[tiffStorage elementAt:
  491.                   ii])->imageName;
  492.                 animDirName = ((ImageStruct *)[tiffStorage elementAt:
  493.                   ii])->animDirName;
  494.                 imageStruct.imageList = nil;
  495.                 imageStruct.imageName = imageName;
  496.                 imageStruct.isSpin = isSpin;
  497.                 imageStruct.isMult = isMult;
  498.                 imageStruct.isAnim = isAnim;
  499.                 imageStruct.animDirName = animDirName;
  500.                 imageStruct.maxAnimFiles = maxAnimFiles;
  501.                 [tiffStorage replaceElementAt:(unsigned int)ii
  502.                   with:&imageStruct];
  503.             }
  504.         }    
  505.     }
  506.     return self;
  507.     
  508. }
  509.  
  510. // creates a tiff record in the tiffStorage for every tiff file encountered.
  511. // the actual tiff lists are built in createTiffs
  512. // looks in Celestial bundle or .Celestial directory in home directory
  513.  
  514. - buildTiffStorage
  515. {
  516. ImageStruct imageStruct; 
  517.  
  518.     tiffStorage = [[Storage allocFromZone:[self zone]] initCount:0
  519.     elementSize:sizeof(imageStruct) description:"{iiii@*}"];
  520.  
  521.     totalTiffCount = [self searchDirectory]; //create list of filenames
  522.            
  523.     return self;
  524. }
  525.  
  526. - setTiffDirectory: (char *)directory
  527. {
  528.     strcpy(tiffDirectory,directory);
  529.     return self;
  530. }
  531.  
  532. - (BOOL)isOk:(char *)filename :(int *)isAnim :(int *)isMult :(int *)isSpin
  533. //checks to make sure the filename is .tiff
  534. //sets flags for rotate,anim and mult options
  535.  
  536. char *suffix;
  537.  
  538.     *isSpin = 0;
  539.     *isMult = 0;
  540.     *isAnim = 0;
  541.     
  542.     suffix = rindex(filename,'.');
  543.     if (suffix == 0)
  544.         return NO;
  545.         
  546.     else if(strlen(suffix) != 5)
  547.         return NO;
  548.         
  549.     else if(strncmp(suffix,".tiff",5) == 0){
  550.         *suffix  = '\0';     /* strip tiff suffix */
  551.         if([self stringMatch:"mult" :filename])
  552.              *isMult = 1;
  553.         if([self stringMatch:"spin" :filename])
  554.              *isSpin = 1;
  555.         return YES;
  556.         
  557.     }
  558.     else if(strncmp(suffix,".anim",5) == 0){
  559.         *suffix  = '\0';     /* strip anim suffix */
  560.         *isAnim = 1;
  561.         if([self stringMatch:"mult" :filename])
  562.              *isMult = 1;
  563.         if([self stringMatch:"spin" :filename])
  564.              *isSpin = 1;
  565.         return YES;
  566.     }
  567.     else
  568.         return NO;
  569. }
  570.  
  571.  
  572.  
  573. // look in the directory for all the tiff images
  574. //if .anim directory encountered then get count and filename
  575. // create a list of storage objects that will use them
  576. - (int)searchDirectory
  577. {
  578. ImageStruct imageStruct; 
  579. char animDirectory[MAXPATHLEN + 1];
  580. char filename[MAXPATHLEN + 1];
  581. long basep;
  582. char *buf;
  583. struct direct *dp;
  584. int cc, fd, fileCount = 0;
  585. char dirbuf[8192];
  586. int isAnim,isMult,isSpin,animCount;
  587.  
  588.     if ((fd = open(tiffDirectory, O_RDONLY, 0644)) > 0) {
  589.         cc = getdirentries(fd, (buf = dirbuf), 8192, &basep);
  590.         while (cc) {
  591.             dp = (struct direct *)buf;
  592.         
  593.             if ([self isOk:dp->d_name:&isAnim :&isMult :&isSpin]) {
  594.                 imageStruct.isAnim = isAnim;
  595.                 imageStruct.isMult = isMult;
  596.             
  597.                 imageStruct.isSpin = isSpin;
  598.                 animCount = 0;
  599.                 if(isAnim){
  600.                     sprintf(animDirectory,"%s/%s.anim",
  601.                      tiffDirectory,dp->d_name);
  602.                     animCount = (int)[self isAnimOk:animDirectory :filename];
  603.                     if(animCount > 0){
  604.                         imageStruct.imageName = NXCopyStringBufferFromZone
  605.                           (filename,[self zone]);
  606.                         imageStruct.animDirName = NXCopyStringBufferFromZone
  607.                           (dp->d_name,[self zone]);
  608.                         imageStruct.imageList = NULL;
  609.                         imageStruct.maxAnimFiles = animCount;
  610.                         [tiffStorage addElement:&imageStruct];
  611.                         fileCount++;
  612.                     }
  613.                 }
  614.                 else {
  615.                     imageStruct.imageName = NXCopyStringBufferFromZone(dp->d_name,
  616.                          [self zone]);             
  617.                     imageStruct.maxAnimFiles = animCount;
  618.                     imageStruct.imageList = NULL;
  619.                     imageStruct.animDirName = NULL;
  620.                     [tiffStorage addElement:&imageStruct];
  621.                     fileCount++;
  622.  
  623.                 }
  624.             }
  625.             buf += dp->d_reclen;
  626.             if (buf >= dirbuf + cc) {
  627.                 cc = getdirentries(fd, (buf = dirbuf), 8192, &basep);
  628.             }
  629.         }
  630.         close(fd);
  631.  
  632.     }
  633.     return fileCount;
  634. }
  635.  
  636. - (Storage *)returnTiffStorage
  637. {
  638.     return tiffStorage;
  639. }
  640.  
  641. - setHomeDirFile:(char *)path
  642. {
  643. char user[15];
  644. char *getlogin();
  645. char *ptr;
  646. struct passwd *getpwuid(), *pwptr = NULL;
  647.  
  648.     user[0] = 0;
  649.  
  650.     if (((ptr = getlogin()) == NULL) || !user[0])
  651.         {
  652.             if ((pwptr = getpwuid(getuid())) == NULL)
  653.                 sprintf(user, "%d", getuid());
  654.             else
  655.                 strcpy(user, pwptr->pw_name);
  656.         }
  657.  
  658.     if(user){
  659.     strcpy(path,pwptr->pw_dir);
  660.     strcat(path,"/.Celestial");
  661.     }
  662.    return self;    
  663. }
  664. - (BOOL)stringMatch:(char *)string1 : (char *)string2
  665. {
  666.         while(*string2 != '\0'){
  667.             if(strncasecmp(string1,string2,1) == 0){
  668.                 if(strncasecmp(string1, string2, strlen(string1)) == 0){
  669.                     return YES;
  670.                 }
  671.                 else{
  672.                     string2++;
  673.  
  674.                 }
  675.             }
  676.             else
  677.                 string2++;
  678.         }
  679.         return NO;
  680. }
  681.  
  682. // look in the anim directory for all the tiff images
  683. // it will return the name of the first file that is named filename.1.tiff
  684.         
  685. - (int)isAnimOk: (char *)directory :(char *)filename 
  686. {
  687. // look in the anim directory for all the tiff images
  688. // it will return the name of the file that is named filename.1.tiff
  689. // otherwise return NULL
  690.  
  691. long basep;
  692. char *buf;
  693. struct direct *dp;
  694. int cc = 0;
  695. int fd = 0;
  696. short found = 0;
  697. int fileCount = 0;
  698. char dirbuf[8192];
  699. char *suffix = NULL;
  700.  
  701.     
  702.     if ((fd = open(directory, O_RDONLY, 0644)) > 0) {
  703.         cc = getdirentries(fd, (buf = dirbuf), 8192, &basep);
  704.         while (cc) {
  705.             dp = (struct direct *)buf;
  706.             
  707.             suffix = rindex(dp->d_name,'.');
  708.             if(strncmp(suffix,".tiff",5) == 0){
  709.                 if (!found && [self stringMatch:".1.tiff" :dp->d_name]){
  710.                     found = 1; //if found don't look anymore
  711.                     strncpy(filename,dp->d_name,
  712.                      strlen(dp->d_name)-7);
  713.                     filename[(strlen(dp->d_name)-7)] = '\0';
  714.                     
  715.                 }
  716.                 fileCount++;
  717.  
  718.             }
  719.             
  720.             buf += dp->d_reclen;
  721.             if (buf >= dirbuf + cc) {
  722.                 cc = getdirentries(fd, (buf = dirbuf), 8192, &basep);
  723.             }
  724.         }
  725.     }
  726.     close(fd);
  727.     if(!found) // there was no file "file.1.tiff" in anim dir
  728.         fileCount = 0;
  729.     return fileCount;
  730. }
  731. @end
  732.